package InnerClass.memberclass;

public class Classroom {

    private String classname;

    private InnerStudent innerStudent;

    public Classroom(String classname) {
        this.classname = classname;
    }

    public InnerStudent getStudent(){
        if (innerStudent == null) {
            this.innerStudent = new InnerStudent("xiaosong","男");
        }
        return innerStudent;
    }

    public String getClassname() {
        return classname;
    }

    @Override
    public String toString() {
        return "Classroom{" +
                "classname='" + classname + '\'' +
                '}';
    }

    /**
     * 内部类可以拥有 private 访问权限、protected 访问权限、public 访问权限及包访问权限。
     * 比如上面的例子，如果成员内部类 Inner 用 private 修饰，则只能在外部类的内部访问，
     * 如果用 public 修饰，则任何地方都能访问；
     * 如果用 protected 修饰，则只能在同一个包下或者继承外部类的情况下访问；
     * 如果是默认访问权限，则只能在同一个包下访问。
     * 这一点和外部类有一点不一样，外部类只能被 public 和包访问（default）两种权限修饰
     *
     * 成员内部类可以无条件访问外部类的所有成员属性和成员方法（包括private成员和静态成员）
     */
    class InnerStudent{

        /**
         * 成员内部类拥有和外部类同名的成员变量或者方法时，
         * 会发生隐藏现象，即默认情况下访问的是成员内部类的成员
         */
        private String classname;

        private String sname;

        private String gender;

        public InnerStudent(String classname, String sname, String gender) {
            this.classname = classname;
            this.sname = sname;
            this.gender = gender;
        }

        public InnerStudent(String sname, String gender) {
            this.sname = sname;
            this.gender = gender;
        }

        @Override
        public String toString() {
            return "InnerStudent{" +
                    "classname='" + classname + '\'' +
                    ", sname='" + sname + '\'' +
                    ", gender='" + gender + '\'' +
                    '}';
        }

        public String getClassname() {
            return classname;
        }
    }

    public static void main(String[] args) {
        //成员内部类是依附外部类而存在，如果要创建成员内部类的对象，前提是必须存在一个外部类的对象。
        // 创建成员内部类对象的一般方式如下：
        // 1.
        Classroom classroom = new Classroom("7");
        System.out.println("classroom:"+classroom);
        Classroom.InnerStudent innerStudent1 = classroom.new InnerStudent("liuwz","男");
        System.out.println("innerStudent1"+innerStudent1);
        //2.使用内部方法获取内部类的形式(更喜欢这种)
        InnerStudent student = classroom.getStudent();
        System.out.println("innerStudent1"+innerStudent1);
        Classroom.InnerStudent innerStudent2 = classroom.new InnerStudent("10班","liuwz","男");
        System.out.println("innerStudent2"+innerStudent2);

        /**
         * 成员内部类拥有和外部类同名的成员变量或者方法时，
         * 会发生隐藏现象，即默认情况下访问的是成员内部类的成员
         *
         * 如下就是当前内部成员获取的是   自己的 班级信息，而不是 依附的外部类对象的属性
         */
        System.out.println("获取班级信息为:"+classroom.innerStudent.getClassname()+",innerStudent2:"+ innerStudent2.getClassname());

        /**
         * 内部类访问外部类 同名的属性
         */


    }


}
